/**
 * Created by wm123 on 2017/6/28.
 */
const extend = require('extend');

const { Board } = require('board-game');
const questions = require('./questions');
const language = require('./language');

const flat = (questions, tips, names, result) => {
    let keys = Object.keys(questions);
    for (let key of keys) {
        let sub = questions[key];
        if (key === 'other') {
            result.push(...sub.map(value => ({ answer: value, tips })))
        } else if (!(sub instanceof Array)) {
            flat(sub, [...tips, language[[...names, key].join('_')]], [...names, key], result);
        } else {
            result.push(...sub.map(value => ({ answer: value, tips: [...tips, language[[...names, key].join('_')]] })))
        }
    }
    return result;
}
const flatQuestions = flat(questions, [], [], []);
for(let question of flatQuestions) {
    console.log(question.answer, question.tips);
}

const initial = {
    get size() { return 'normal' },
    get color() { return 'red' },
    get background() { return 'white' },
};

class GuessDrawBoard extends Board {
    constructor(game) {
        super(game);
        this.configs = this.game.groups.map(group => group.roles.map(() => ({ ...initial })));
        this.scores = new Array(this.game.groups.length).fill(0);
        this.question = GuessDrawBoard.randomQuestion();
        this.prev = '';
        this.round = 0;
        this.drawGroup = 0;
        this.drawRole = 0;
        this.current = {
            status: '',
            at: 0
        };
        this.rights = [];
        this.count = {
            good: 0,
            bad: 0
        };
    }
    get drawer() {
        return this.game.groups[this.drawGroup].roles[this.drawRole];
    }
    get config() {
        return this.configs[this.drawGroup][this.drawRole];
    }
    get time() {
        return Math.round((Date.now() - this.current.at) / 1000);
    }
    get status() {
        return this.current.status;
    }
    set status(status) {
        if (status !== this.current.status) {
            this.current.status = status;
            this.current.at = Date.now();
            this.count.good = 0;
            this.count.bad = 0;
        }
    }
    init() {
        this.status = 'waiting';
    }
    setColor(color) {
        this.config.color = color;
    }
    setSize(size) {
        this.config.size = size;
    }
    setBackground(background) {
        this.config.background = background;
    }
    next() {
        this.rights = [];
        this.prev = this.question.answer;
        this.question = GuessDrawBoard.randomQuestion();
        this.drawRole++;
        if (this.drawRole >= this.game.groups[this.drawGroup].roles.length) {
            this.drawRole = 0;
            this.drawGroup++;
            if (this.drawGroup >= this.game.groups.length) {
                this.drawGroup = 0;
                this.round++;
                return true;
            }
        }
        return false;
    }
    noHandled() {
        let score = Math.min(10, this.scores[this.drawer.group]);
        this.scores[this.drawer.group] -= score;
        return score;
    }
    noRight() {
        let score = Math.min(this.game.groups.length - 1, this.scores[this.drawer.group]);
        this.scores[this.drawer.group] -= score;
        return score;
    }
    answer(role, answer) {
        if (answer.replace(/\s+/ig, '').toLowerCase() === this.question.answer.toLowerCase()) {
            if (this.status === 'drawing') {
                if (role !== this.drawer && !this.rights.includes(role)) {
                    let guesser = this.time < this.game.room.settings.draw / 4 ? 3 : this.time < this.game.room.settings.draw / 2 ? 2 : 1;
                    let drawer = this.rights.length === 3 ? 3 : this.rights.length === 2 ? 2 : this.rights.length === 1 ? 1 : 2
                    this.scores[role.group] += guesser;
                    this.scores[this.drawer.group] += drawer;
                    this.rights.push(role);
                    return { guesser, drawer };
                } else {
                    return 0;
                }
            } else {
                if (role === this.drawer) {
                    return 0;
                } else {
                    return false;
                }
            }
        } else {
            return false;
        }
    }
    good() {
        this.count.good++;
    }
    bad() {
        this.count.bad++;
    }
    isAllRight() {
        return this.rights.length === this.game.groups.reduce((s, group) => s + group.roles.length, 0) - 1;
    }
    isWin(groupIndex) {
        let score = this.scores[groupIndex];
        return Math.max(...this.scores) === score && this.scores.filter(s => s === score).length === 1;
    }
    get data() {
        return extend(true, super.data, {
            drawer: this.drawer.data,
            config: this.config,
            question: this.question,
            prev: this.prev,
            status: this.status,
            time: this.time,
            round: this.round,
            count: {
                good: this.count.good,
                bad: this.count.bad
            },
            scores: this.scores.slice()
        });
    }
    static randomQuestion(obj = questions, names = []) {
        return flatQuestions[Math.floor(flatQuestions.length * Math.random())];
        // let keys = Object.keys(obj);
        // let key = keys[parseInt(keys.length * Math.random())];
        // let value = obj[key];
        // if (typeof value === 'object' && Object.keys(value).length) {
        //     let question = GuessDrawBoard.randomQuestion(value, key === 'other' ? names : names.concat(key));
        //     return { answer: question.answer, tips: key === 'other' ? question.tips || [] : [ language[names.concat(key).join('_')] ].concat(question.tips || []) }
        // } else {
        //     return { answer: value };
        // }
    }
}

module.exports = GuessDrawBoard;